package com.xhwl.data.controller;


import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xhwl.common.dto.cent.sdata.space.*;
import com.xhwl.common.enums.BusinessRangeTypeEnum;
import com.xhwl.common.enums.ImportStatus;
import com.xhwl.common.enums.OrganizationTypeEnum;
import com.xhwl.common.enums.config.IndustryEnum;
import com.xhwl.common.enums.space.ViewType;
import com.xhwl.common.pojo.ResultJson;
import com.xhwl.common.pojo.cent.sdata.*;
import com.xhwl.common.pojo.cent.sdata.space.OrganizationImport;
import com.xhwl.common.pojo.cent.sdata.space.SpaceConfigDTO;
import com.xhwl.common.pojo.cent.sdata.space.SpaceConfigQuery;
import com.xhwl.common.pojo.config.OrganizationConfig;
import com.xhwl.common.pojo.msg.NoticeData;
import com.xhwl.common.pojo.msg.Target;
import com.xhwl.common.query.OrganizationConfigQuery;
import com.xhwl.common.query.cent.sdata.OrganizationQuery;
import com.xhwl.common.query.cent.sdata.SpaceImportQuery;
import com.xhwl.common.query.cent.sdata.SpaceQuery;
import com.xhwl.common.query.cent.sysconfig.OrganizationConfigPageQuery;
import com.xhwl.common.utils.DateUtils;
import com.xhwl.common.utils.StringUtils;
import com.xhwl.common.utils.excel.ExcelUtils;
import com.xhwl.data.pojo.dto.OrganizationConfigDTO;
import com.xhwl.data.service.*;
import com.xhwl.data.util.SpaceUtil;
import lombok.Data;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Author: luyi
 * @Description:
 * @Date: Create in 17:41 2021/1/22
 */
@RestController
public class SpaceController {

    @Autowired
    private ISpaceService spaceService;

    @Autowired
    private IOrganizationTypeService organizationTypeService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private IOrganizationImportService organizationImportService;

    @Autowired
    private IOrganizationConfigService organizationConfigService;

    @Autowired
    private IOrganizationConfigFeignService organizationConfigFeignService;

    @Autowired
    private IOrganizationService organizationService;

    @Autowired
    private IMessageCentService messageCentService;

    @Autowired
    private IIndustryService industryService;

	private final static String EXCEL2003 = "xls";
	private final static String EXCEL2007 = "xlsx";

    private static final Logger log = LoggerFactory.getLogger(SpaceController.class);

    private static final ExecutorService EXECUTOR_SERVICE = Executors.newSingleThreadExecutor();

    @RequestMapping("/space/insert")
    public ResultJson insert(@RequestBody Space space) {
		if(StringUtils.isEmpty(space.getName()) || space.getName().length() > 32){
			return ResultJson.fail("名称输入错误");
		}
		if(StringUtils.isNotEmpty(space.getCode()) && space.getCode().length() > 50){
			return ResultJson.fail("编码输入错误");
		}
		if(null == space.getType()){
			return ResultJson.fail("缺少空间类型");
		}

		QueryWrapper<OrganizationType> organizationTypeQueryWrapper = new QueryWrapper<>();
		organizationTypeQueryWrapper.eq("id", space.getType());
		organizationTypeQueryWrapper.select("id");
		List<OrganizationType> list = organizationTypeService.list(organizationTypeQueryWrapper);
		if(list.isEmpty()){
			return ResultJson.fail("空间类型错误");
		}
		if (null == space.getParentId()) {
            return ResultJson.fail("缺少上级参数");
        }
        return spaceService.create(space);
    }

    @RequestMapping(value = "/space/batch-insert")
    public ResultJson batchInsert(@RequestBody List<Space> space) {
        if (CollectionUtils.isEmpty(space)) {
            return ResultJson.fail("参数错误");
        }
		for (Space space1 : space) {
			if(StringUtils.isEmpty(space1.getName()) || space1.getName().length() > 32){
				return ResultJson.fail("名称输入错误");
			}
			if(StringUtils.isNotEmpty(space1.getCode()) && space1.getCode().length() > 20){
				return ResultJson.fail("编码输入错误");
			}
			if(null == space1.getType()){
				return ResultJson.fail("缺少空间类型");
			}
			if (null == space1.getParentId()) {
				return ResultJson.fail("缺少上级参数");
			}
		}
		List<Integer> types = space.stream().map(i -> i.getType()).distinct().collect(Collectors.toList());
		QueryWrapper<OrganizationType> organizationTypeQueryWrapper = new QueryWrapper<>();
		organizationTypeQueryWrapper.in("id", types);
		organizationTypeQueryWrapper.select("id");
		List<OrganizationType> list = organizationTypeService.list(organizationTypeQueryWrapper);
		if(list.size() != types.size()){
			return ResultJson.fail("空间类型错误");
		}
		return spaceService.batchCreate(space);
    }

    @RequestMapping("/space/list")
    public ResultJson list(@RequestBody SpaceQuery spaceQuery) {
        List<Space> result = spaceService.list(spaceQuery);
        return ResultJson.success(result);
    }

    @RequestMapping("/space/page")
    public ResultJson page(@RequestBody SpaceQuery spaceQuery, Page page) {
//        page.setOrders(OrderItem.descs("id"));
        Page<Space> result = spaceService.page(spaceQuery, page);
		if(result != null && CollectionUtil.isNotEmpty(result.getRecords())){
			for(Space vo :result.getRecords()){
				dealJson (vo,spaceQuery.getTypeId());
			}
		}
        return ResultJson.success(result);
    }

    @RequestMapping("/space/detail")
    public ResultJson detail(@RequestParam(required = false) Integer id, @RequestParam(required = false) Integer orgId,Integer typeId) {
        if (null == id && null == orgId) {
            return ResultJson.fail("参数错误");
        }
        QueryWrapper<Space> queryWrapper = new QueryWrapper<>();
        if (null != id) {
            queryWrapper.eq("id", id);
        }
        if (null != orgId) {
            queryWrapper.eq("org_id", orgId);
        }
		Space space = spaceService.getOne(queryWrapper);
		dealJson (space,typeId);
		return ResultJson.success(space);
    }

    @RequestMapping("/space/name-check")
    public ResultJson nameCheck(@RequestParam(required = false) Integer id, String name, Integer parentId) {
        return spaceService.nameCheck(id, name, parentId);
    }

    @RequestMapping("/space/delete")
    public ResultJson delete(Integer id) {
        return spaceService.delete(id);
    }

    @RequestMapping(value = "/space/field")
    public ResultJson field(Integer id) {
        QueryWrapper<OrganizationType> organizationTypeQueryWrapper = new QueryWrapper<>();
        organizationTypeQueryWrapper.eq("id", id);
        OrganizationType one = organizationTypeService.getOne(organizationTypeQueryWrapper);
        List<Field> result = new ArrayList<>();
        if (ViewType.SPACE_DEFINED == one.getViewType()) {
            String source = one.getSource();
            JSONObject json = JSONObject.parseObject(source);
            if(null == json){
            	return ResultJson.fail("配置错误");
			}
            List fields = (List) json.get("fields");
            if(CollectionUtils.isEmpty(fields)){
            	return ResultJson.fail("数据不兼容");
			}
            for (Object order : fields) {
            	String s = order.toString();
            	JSONObject jsonObject = JSONObject.parseObject(s);
                Field field = new Field();
                field.setCN(String.valueOf(jsonObject.get("label")));
                field.setEN(String.valueOf(jsonObject.get("vModel")));
                result.add(field);
            }
        } else if (ViewType.SPACE == one.getViewType()) {
            result = SpaceUtil.getSpaceFieldMap(OrganizationTypeEnum.valueOfId(one.getId()));
        }
        return ResultJson.success(result);
    }

	/**
	 * 空间批量导入
	 * @param file 上传的excel文件
	 * @param type 空间类型
	 * @param account 操作帐号（获取业态信息）
	 * @return
	 */
	@RequestMapping(value = "/space/batch-import")
	public ResultJson batchImport(@RequestParam MultipartFile file, @RequestParam Integer type, @RequestParam Integer projectId, Account account, @RequestHeader Short industryId){

		log.info("用户 {} 正在使用空间批量导入功能", account.getId());
		account.setIndustryId(industryId);
		final Integer convert = 1024 * 1024;
		double v = (double) file.getSize() / convert;
		Double fileLimit = 10.00;
		if(v > fileLimit){
			return ResultJson.fail("文件大小超过限制");
		}
		OrganizationType organizationType = organizationTypeService.getById(type);
		if(null == organizationType){
			return ResultJson.fail("空间类型错误");
		}
		spaceService.batchImportSpace(file, type, projectId, account);
		return ResultJson.success("正在导入。。。");
	}

	/**
	 * 空间配置
	 * @return
	 */
	@RequestMapping(value = "/space/config/page")
	public ResultJson spaceConfigPage(@RequestBody SpaceConfigQuery spaceConfigQuery){

		QueryWrapper<Industry> industryQueryWrapper = new QueryWrapper<>();
		if(!StringUtils.isEmpty(spaceConfigQuery.getKeywords())){
			industryQueryWrapper.like("name", spaceConfigQuery.getKeywords());
		}
		Page page = industryService.page(spaceConfigQuery.getPage(), industryQueryWrapper);
		List list = viewConvert(page.getRecords());
		page.setRecords(list);
		return ResultJson.success(page);
	}


	/**
	 * 空间结构管理
	 * @return
	 */
	@RequestMapping(value = "/space/construction/management/page")
	public ResultJson spaceConstructionManagementPage(@RequestBody OrganizationConfigPageQuery organizationConfigPageQuery){
		Page page = organizationConfigFeignService.page(organizationConfigPageQuery, organizationConfigPageQuery.getPage());
		List list = setChild(page.getRecords());
		page.setRecords(list);
		return ResultJson.success(page);
	}

	private List<OrganizationConfigDTO> setChild(List<OrganizationConfig> organizationConfigs){
		if(CollectionUtils.isNotEmpty(organizationConfigs)){
			List<Integer> collect = organizationConfigs.stream().map(i -> i.getId()).collect(Collectors.toList());
			OrganizationConfigQuery organizationConfigQuery = new OrganizationConfigQuery();
			organizationConfigQuery.setParentIds(collect);
			List<OrganizationConfig> list = organizationConfigFeignService.list(organizationConfigQuery);
			if(!CollectionUtils.isEmpty(list)){
				Map<Integer, List<OrganizationConfig>> parentIdMap = list.stream().collect(Collectors.groupingBy(OrganizationConfig::getParentId));
				List<OrganizationConfigDTO> organizationConfigDTOs = new ArrayList<>(organizationConfigs.size());
				for (OrganizationConfig organizationConfig : organizationConfigs) {
					OrganizationConfigDTO organizationConfigDTO1 = new OrganizationConfigDTO();
					BeanUtils.copyProperties(organizationConfig, organizationConfigDTO1);
					organizationConfigDTO1.setChildren(convertDTO(parentIdMap.get(organizationConfig.getId())));
					organizationConfigDTOs.add(organizationConfigDTO1);
				}
				return organizationConfigDTOs;
			}
		}
		return Collections.emptyList();
	}

	private List<OrganizationConfigDTO> convertDTO(List<OrganizationConfig> organizationConfigs1){
		List<OrganizationConfigDTO> organizationConfigDTOs1 = new ArrayList<>();
		if(!CollectionUtils.isEmpty(organizationConfigs1)){
			for (OrganizationConfig config : organizationConfigs1) {
				OrganizationConfigDTO organizationConfigDTO = new OrganizationConfigDTO();
				BeanUtils.copyProperties(config, organizationConfigDTO);
				organizationConfigDTOs1.add(organizationConfigDTO);
			}
		}
		return organizationConfigDTOs1;
	}

	private List viewConvert(List<Industry> records) {
		if(!CollectionUtils.isEmpty(records)){
			List<Integer> ids = records.stream().map(i -> i.getId()).collect(Collectors.toList());
			OrganizationConfigQuery organizationConfigQuery = new OrganizationConfigQuery();
			organizationConfigQuery.setIndustryIds(ids);
			organizationConfigQuery.setRanges(Arrays.asList(BusinessRangeTypeEnum.DEFAULT));
			List<OrganizationConfig> list = organizationConfigFeignService.list(organizationConfigQuery);
			Map<Integer, OrganizationConfig> configMap = list.stream().collect(Collectors.toMap(OrganizationConfig::getIndustryId, Function.identity(), (key1, key2) -> key1));
			List<SpaceConfigDTO> spaceConfigDTOS = new ArrayList<>(records.size());
			for (Industry record : records) {
				SpaceConfigDTO spaceConfigDTO = new SpaceConfigDTO();
				BeanUtils.copyProperties(record, spaceConfigDTO);
				spaceConfigDTO.setStatus(null != configMap.get(record.getId()));
				spaceConfigDTOS.add(spaceConfigDTO);
			}
			return spaceConfigDTOS;
		}
		return records;
	}

	/**
	 * 记录导入信息
	 * @param total
	 * @param listResultJson
	 * @param projectId
	 * @param organizationImport
	 */
	private void record(int total, ResultJson<List<ErrorSpace>> listResultJson, int projectId, OrganizationImport organizationImport, Account account){
		organizationImport.setStatus(ImportStatus.COMPLETED);
		List<ErrorSpace> result = listResultJson.getResult();
		StringBuilder sbd = new StringBuilder();
		if(CollectionUtils.isEmpty(result)){
			sbd.append("全部成功，共").append(total);
			organizationImport.setIsCompletedSuccess(true);
		}else if(result.size() == total){
			sbd.append("全部失败, 共").append(total);
			organizationImport.setIsCompletedSuccess(false);
			String fileId = UUID.randomUUID().toString().replaceAll("-", "");
			organizationImport.setFileId(fileId);
			redisTemplate.opsForValue().set(fileId, result, 7, TimeUnit.DAYS);
		}else{
			sbd.append("成功").append(total - result.size()).append("，失败").append(result.size()).append("，共").append(total);
			organizationImport.setIsCompletedSuccess(false);
			String fileId = UUID.randomUUID().toString().replaceAll("-", "");
			organizationImport.setFileId(fileId);
			redisTemplate.opsForValue().set(fileId, result, 7, TimeUnit.DAYS);
		}
		organizationImport.setImportResult(sbd.toString());
		organizationImport.setProjectId(projectId);
		organizationImport.setAccountId(account.getId());
		organizationImportService.updateById(organizationImport);

		// 通知用户上传完毕了
		NoticeData noticeData = new NoticeData();
		noticeData.setTitle("UPLOAD_SPACE_FINISHED");
		Map<String, String> map = new HashMap<>();
		map.put("total", String.valueOf(total));
		map.put("fail", String.valueOf(result.size()));
		map.put("fileId", organizationImport.getFileId());
		map.put("typeId", String.valueOf(organizationImport.getType()));
		map.put("recordId", String.valueOf(organizationImport.getId()));
		noticeData.setParams(map);
		// 消息分类
		noticeData.setCategory(Arrays.asList("space_import"));
		log.info("通知用户 {} 记录id {} 已经上传完成了", account.getId(), organizationImport.getId());
		try {
			Target target = new Target();
			target.setReceivers(Arrays.asList(account.getId().toString()));
			ResultJson resultJson = messageCentService.send("websocket", noticeData, target);
			log.info("消息发送结果 {}", JSONObject.toJSONString(resultJson));
		}catch (Exception e){
			log.info("上传完毕，通知用户失败了 {}", e.getMessage());
		}

	}

	/**
	 * 空间导入历史分页
	 * @param spaceImportQuery
	 * @param page
	 * @return
	 */
	@RequestMapping(value = "/space/import-history")
	public ResultJson importHistory(@RequestBody SpaceImportQuery spaceImportQuery, Page<OrganizationImport> page){

		page.setOrders(OrderItem.descs("created_at"));
		if(null == spaceImportQuery){
			return ResultJson.fail("参数错误");
		}
		QueryWrapper<OrganizationImport> organizationImportQueryWrapper = new QueryWrapper<>();
		organizationImportQueryWrapper. eq("project_id", spaceImportQuery.projectId);
		if(null != spaceImportQuery.status){
			organizationImportQueryWrapper.eq("status", spaceImportQuery.status);
		}
		if(!StringUtils.isEmpty(spaceImportQuery.fileName)){
			organizationImportQueryWrapper.like("file_name", spaceImportQuery.fileName);
		}
		organizationImportQueryWrapper.ge("created_at", DateUtils.nextDay(-7));
		Page<OrganizationImport> page1 = organizationImportService.page(page, organizationImportQueryWrapper);
		return ResultJson.success(page1);
	}

	/**
	 * 导出错误信息
	 * @param response
	 * @param typeId 获取导出的模版
	 * @param fileId 获取数据
	 */
	@RequestMapping(value = "/space/export-error")
	public void downloadError(HttpServletResponse response, @RequestParam Integer typeId, @RequestParam String fileId, @RequestHeader Short industryId){

		OrganizationType organizationType = organizationTypeService.getById(typeId);
		if(null == organizationType){
			log.warn("空间类型不存在");
		}

		QueryWrapper<OrganizationImport> organizationImportQueryWrapper = new QueryWrapper<>();
		organizationImportQueryWrapper.eq("file_id", fileId);
		organizationImportQueryWrapper.le("created_at", DateUtils.nextDay(7));
		OrganizationImport one = organizationImportService.getOne(organizationImportQueryWrapper);
		if(null == one){
			log.warn("文件不存在");
		}
		if("building".equals(organizationType.getCode()) || "room".equals(organizationType.getCode()) || "floor".equals(organizationType.getCode()) || "public-area".equals(organizationType.getCode())
				|| "area".equals(organizationType.getCode())|| "unit".equals(organizationType.getCode())|| "balcony".equals(organizationType.getCode())|| "block".equals(organizationType.getCode())){
			List<ErrorSpace<Object>> records = (List) redisTemplate.opsForValue().get(fileId);
			if(CollectionUtils.isEmpty(records)){
				log.warn("文件不存在");
			}
			Workbook wb = new XSSFWorkbook();
			importResult(typeId, wb, records);
			buildExcelDocument(fileId + ".xlsx", wb, response);
		}else{
			//log.warn("错误的类型");
			List<ErrorSpace<JSONObject>> records = (List) redisTemplate.opsForValue().get(fileId);
			if(CollectionUtils.isEmpty(records)){
				log.warn("文件不存在");
			}
			Workbook wb = new XSSFWorkbook();
			spaceImportResult(typeId, wb, records);
			buildExcelDocument(fileId + ".xlsx", wb, response);
		}
		//if(ViewType.SPACE == organizationType.getViewType()){
			/*if("building".equals(organizationType.getCode())){
				List<ErrorSpace<BuildingExcelDTO>> records = (List) redisTemplate.opsForValue().get(fileId);
				if(CollectionUtils.isEmpty(records)){
					log.warn("文件不存在");
				}
				List<BuildingExcelErrorDTO> b = records.stream().map(i -> {
					BuildingExcelErrorDTO buildingExcelErrorDTO = new BuildingExcelErrorDTO();
					BuildingExcelDTO buildingExcelDTO = i.getObj();
					BeanUtils.copyProperties(buildingExcelDTO, buildingExcelErrorDTO);
					buildingExcelErrorDTO.setReason(i.getReason());
					return buildingExcelErrorDTO;
				}).collect(Collectors.toList());
				buildingImportResult(response, industryId, b, fileId + ".xlsx");
			}else if("room".equals(organizationType.getCode())){
				List<ErrorSpace<RoomExcelDTO>> records = (List) redisTemplate.opsForValue().get(fileId);
				if(CollectionUtils.isEmpty(records)){
					log.warn("文件不存在");
				}
				List<RoomExcelErrorDTO> b = records.stream().map(i -> {
					RoomExcelErrorDTO roomExcelErrorDTO = new RoomExcelErrorDTO();
					RoomExcelDTO roomExcelDTO = i.getObj();
					BeanUtils.copyProperties(roomExcelDTO, roomExcelErrorDTO);
					roomExcelErrorDTO.setReason(i.getReason());
					return roomExcelErrorDTO;
				}).collect(Collectors.toList());
				roomImportResult(response, industryId, b, fileId + ".xlsx");
			}else if("floor".equals(organizationType.getCode())){
				List<ErrorSpace<FloorExcelDTO>> records = (List) redisTemplate.opsForValue().get(fileId);
				if(CollectionUtils.isEmpty(records)){
					log.warn("文件不存在");
				}
				List<FloorExcelErrorDTO> b = records.stream().map(i -> {
					FloorExcelErrorDTO floorExcelErrorDTO = new FloorExcelErrorDTO();
					FloorExcelDTO floorExcelDTO = i.getObj();
					BeanUtils.copyProperties(floorExcelDTO, floorExcelErrorDTO);
					floorExcelErrorDTO.setReason(i.getReason());
					return floorExcelErrorDTO;
				}).collect(Collectors.toList());
				floorImportResult(response, industryId, b, fileId + ".xlsx");
			}else if("public-area".equals(organizationType.getCode())){
				List<ErrorSpace<PublicAreaExcelDTO>> records = (List) redisTemplate.opsForValue().get(fileId);
				if(CollectionUtils.isEmpty(records)){
					log.warn("文件不存在");
				}
				List<PublicAreaExcelErrorDTO> b = records.stream().map(i -> {
					PublicAreaExcelErrorDTO publicAreaExcelErrorDTO = new PublicAreaExcelErrorDTO();
					PublicAreaExcelDTO publicAreaExcelDTO = i.getObj();
					BeanUtils.copyProperties(publicAreaExcelDTO, publicAreaExcelErrorDTO);
					publicAreaExcelErrorDTO.setReason(i.getReason());
					return publicAreaExcelErrorDTO;
				}).collect(Collectors.toList());
				publicAreaImportResult(response, industryId, b, fileId + ".xlsx");
			}else if("area".equals(organizationType.getCode())){
				List<ErrorSpace<AreaExcelDTO>> records = (List) redisTemplate.opsForValue().get(fileId);
				if(CollectionUtils.isEmpty(records)){
					log.warn("文件不存在");
				}
				List<AreaExcelErrorDTO> b = records.stream().map(i -> {
					AreaExcelErrorDTO areaExcelErrorDTO = new AreaExcelErrorDTO();
					AreaExcelDTO areaExcelDTO = i.getObj();
					BeanUtils.copyProperties(areaExcelDTO, areaExcelErrorDTO);
					areaExcelErrorDTO.setReason(i.getReason());
					return areaExcelErrorDTO;
				}).collect(Collectors.toList());
				areaImportResult(response, industryId, b, fileId + ".xlsx");
			}else if("unit".equals(organizationType.getCode())){
				List<ErrorSpace<UnitExcelDTO>> records = (List) redisTemplate.opsForValue().get(fileId);
				if(CollectionUtils.isEmpty(records)){
					log.warn("文件不存在");
				}
				List<UnitExcelErrorDTO> b = records.stream().map(i -> {
					UnitExcelErrorDTO unitExcelErrorDTO = new UnitExcelErrorDTO();
					UnitExcelDTO unitExcelDTO = i.getObj();
					BeanUtils.copyProperties(unitExcelDTO, unitExcelErrorDTO);
					unitExcelErrorDTO.setReason(i.getReason());
					return unitExcelErrorDTO;
				}).collect(Collectors.toList());
				unitImportResult(response, industryId, b, fileId + ".xlsx");
			}else if("balcony".equals(organizationType.getCode())){
				List<ErrorSpace<BalconyExcelDTO>> records = (List) redisTemplate.opsForValue().get(fileId);
				if(CollectionUtils.isEmpty(records)){
					log.warn("文件不存在");
				}
				List<BalconyExcelErrorDTO> b = records.stream().map(i -> {
					BalconyExcelErrorDTO balconyExcelErrorDTO = new BalconyExcelErrorDTO();
					BalconyExcelDTO balconyExcelDTO = i.getObj();
					BeanUtils.copyProperties(balconyExcelDTO, balconyExcelErrorDTO);
					balconyExcelErrorDTO.setReason(i.getReason());
					return balconyExcelErrorDTO;
				}).collect(Collectors.toList());
				balconyImportResult(response, industryId, b, fileId + ".xlsx");
			}else if("block".equals(organizationType.getCode())){
				List<ErrorSpace<BlockExcelDTO>> records = (List) redisTemplate.opsForValue().get(fileId);
				if(CollectionUtils.isEmpty(records)){
					log.warn("文件不存在");
				}
				List<BlockExcelErrorDTO> b = records.stream().map(i -> {
					BlockExcelErrorDTO blockExcelErrorDTO = new BlockExcelErrorDTO();
					BlockExcelDTO blockExcelDTO = i.getObj();
					BeanUtils.copyProperties(blockExcelDTO, blockExcelErrorDTO);
					blockExcelErrorDTO.setReason(i.getReason());
					return blockExcelErrorDTO;
				}).collect(Collectors.toList());
				blockImportResult(response, industryId, b, fileId + ".xlsx");
			}else{
				//log.warn("错误的类型");
				List<ErrorSpace<Space>> records = (List) redisTemplate.opsForValue().get(fileId);
				if(CollectionUtils.isEmpty(records)){
					log.warn("文件不存在");
				}
				Workbook wb = new XSSFWorkbook();
				spaceImportResult(typeId, wb, records);
				buildExcelDocument(fileId + ".xlsx", wb, response);
			}*/
		/*}else if(ViewType.SPACE_DEFINED == organizationType.getViewType()){
			List<ErrorSpace<Space>> records = (List) redisTemplate.opsForValue().get(fileId);
			if(CollectionUtils.isEmpty(records)){
				log.warn("文件不存在");
			}
			Workbook wb = new XSSFWorkbook();
			spaceImportResult(typeId, wb, records);
			buildExcelDocument(fileId + ".xlsx", wb, response);
		}else{
			log.warn("错误的类型");
		}*/
	}

	/**
	 * 自定义错误
	 */
	public void importResult(Integer typeId, Workbook wb, List<ErrorSpace<Object>> data){

		OrganizationType organizationType = organizationTypeService.getById(typeId);
		JSONObject jsonObject = JSONObject.parseObject(organizationType.getSource());
		List<String> fields = new ArrayList<>();
		Map<String, String> map = new HashMap<>();
		JSONArray jsonArray = jsonObject.getJSONArray("fields");
		if (jsonArray != null && jsonArray.size() > 0) {
			for (int i = 0; i < jsonArray.size(); i++) {
				if ("sortField".equals(jsonArray.getJSONObject(i).getString("vModel"))){
					continue;
				}
				if("fc-map-fence".equals(jsonArray.getJSONObject(i).getString("tag"))){
					continue;
				}
				fields.add(jsonArray.getJSONObject(i).getString("vModel"));
				map.put(jsonArray.getJSONObject(i).getString("vModel"), jsonArray.getJSONObject(i).getString("label"));
			}
		}
		// 导入模版
		writeSpaceTemplateExcel(fields, jsonObject, wb,map,organizationType.getName());
		// 在最后增加一个‘原因’列
		Sheet sheet = wb.getSheetAt(0);
		Integer cellIndex = fields.size() + 2;
		Cell reasonCell = sheet.getRow(1).createCell(cellIndex);
		reasonCell.setCellValue("原因");
		// 写入数据
		int rowNum = 2;
		for (ErrorSpace<Object> datum : data) {
			Row row = sheet.createRow(rowNum);
			JSONObject object = JSON.parseObject(JSON.toJSONString(datum.getObj()));
			JSONObject jsonObj = object;
			if(object.getJSONObject("expand") != null){
				jsonObj = object.getJSONObject("expand");
			}
			// 上级空间名称和上级空间编码
			Cell cell = row.createCell(0);
			cell.setCellValue(jsonObj.getString("parentName"));
			Cell cell1 = row.createCell(1);
			cell1.setCellValue(jsonObj.getString("parentChainCode"));
			int cellNum = 2;
			for (String field : fields) {
				Cell cell2 = row.createCell(cellNum);
				cell2.setCellValue(jsonObj.getString(field));
				cellNum ++;
			}
			// 原因
			Cell cell3 = row.createCell(cellNum);
			cell3.setCellValue(datum.getReason());
			rowNum ++;
		}
	}

	private void blockImportResult(HttpServletResponse response, Short industryId, List<BlockExcelErrorDTO> data, String fileName) {
		String errorFilePath = getErrorFilePath(OrganizationTypeEnum.BLOCK.id.intValue(), industryId);
		InputStream is = null;
		try {
			is = new FileInputStream(errorFilePath);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		Workbook workbook = null;
		if (fileName.endsWith(EXCEL2007)) {
			try {
				workbook = new XSSFWorkbook(is);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		if (fileName.endsWith(EXCEL2003)) {
			try {
				workbook = new HSSFWorkbook(is);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		// 设置格式
		Sheet sheet = workbook.getSheetAt(0);
		CellStyle cellStyle = workbook.createCellStyle();
		cellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
		cellStyle.setAlignment(HorizontalAlignment.CENTER);
		Font font = workbook.createFont();
		cellStyle.setFont(font);
		ExcelUtils.setByColName(data, BlockExcelErrorDTO.class, sheet, 2);
		ExcelUtils.buildExcelDocument(fileName, workbook, response);
	}

	private void balconyImportResult(HttpServletResponse response, Short industryId, List<BalconyExcelErrorDTO> data, String fileName) {
		String filePath = getFilePath(OrganizationTypeEnum.BALCONY.id.intValue(), industryId);
		InputStream is = null;
		try {
			is = new FileInputStream(filePath);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		Workbook workbook = null;
		if (fileName.endsWith(EXCEL2007)) {
			try {
				workbook = new XSSFWorkbook(is);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		if (fileName.endsWith(EXCEL2003)) {
			try {
				workbook = new HSSFWorkbook(is);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		// 设置格式
		Sheet sheet = workbook.getSheetAt(0);
		CellStyle cellStyle = workbook.createCellStyle();
		cellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
		cellStyle.setAlignment(HorizontalAlignment.CENTER);
		Font font = workbook.createFont();
		cellStyle.setFont(font);

		if(3 == industryId){
			Row row = sheet.getRow(1);
			Cell cell = row.createCell(4);
			cell.setCellValue("编码");
			cell.setCellStyle(cellStyle);

			Cell cell1 = row.createCell(5);
			cell1.setCellValue("编码");
			cell1.setCellStyle(cellStyle);
		}else{
			Row row = sheet.getRow(1);
			Cell cell = row.createCell(3);
			cell.setCellValue("编码");
			cell.setCellStyle(cellStyle);

			Cell cell1 = row.createCell(4);
			cell1.setCellValue("原因");
			cell1.setCellStyle(cellStyle);
		}

		// 从第三行开始往后写入
		for (int i = 0; i < data.size(); i++) {
			Row row = sheet.createRow(i+2);
			BalconyExcelErrorDTO balconyExcelErrorDTO = data.get(i);
			// 第一列
			Cell cell = row.createCell(0);
			cell.setCellValue(balconyExcelErrorDTO.getParentName());
			cell.setCellStyle(cellStyle);

			// 第二列
			Cell cell2 = row.createCell(1);
			cell2.setCellValue(balconyExcelErrorDTO.getParentChainCode());
			cell2.setCellStyle(cellStyle);

			Cell cell3 = row.createCell(2);
			cell3.setCellValue(balconyExcelErrorDTO.getName());
			cell3.setCellStyle(cellStyle);

			Cell cell4 = row.createCell(3);
			cell4.setCellValue(balconyExcelErrorDTO.getCode());
			cell4.setCellStyle(cellStyle);

			Cell cell5 = row.createCell(4);
			cell5.setCellValue(balconyExcelErrorDTO.getReason());
			cell5.setCellStyle(cellStyle);
		}
		ExcelUtils.buildExcelDocument(fileName, workbook, response);
	}

	private void unitImportResult(HttpServletResponse response, Short industryId, List<UnitExcelErrorDTO> data, String fileName) {
		String filePath = getFilePath(OrganizationTypeEnum.UNIT.id.intValue(), industryId);
		InputStream is = null;
		try {
			is = new FileInputStream(filePath);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		Workbook workbook = null;
		if (fileName.endsWith(EXCEL2007)) {
			try {
				workbook = new XSSFWorkbook(is);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		if (fileName.endsWith(EXCEL2003)) {
			try {
				workbook = new HSSFWorkbook(is);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		// 设置格式
		Sheet sheet = workbook.getSheetAt(0);
		CellStyle cellStyle = workbook.createCellStyle();
		cellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
		cellStyle.setAlignment(HorizontalAlignment.CENTER);
		Font font = workbook.createFont();
		cellStyle.setFont(font);

		if(3 == industryId){
			Row row = sheet.getRow(1);
			Cell cell = row.createCell(4);
			cell.setCellValue("编码");
			cell.setCellStyle(cellStyle);

			Cell cell1 = row.createCell(5);
			cell1.setCellValue("原因");
			cell1.setCellStyle(cellStyle);
		}else{
			Row row = sheet.getRow(1);
			Cell cell = row.createCell(3);
			cell.setCellValue("编码");
			cell.setCellStyle(cellStyle);

			Cell cell1 = row.createCell(4);
			cell1.setCellValue("原因");
			cell1.setCellStyle(cellStyle);
		}

		// 从第三行开始往后写入
		for (int i = 0; i < data.size(); i++) {
			Row row = sheet.createRow(i+2);
			UnitExcelErrorDTO unitExcelErrorDTO = data.get(i);
			// 第一列
			Cell cell = row.createCell(0);
			cell.setCellValue(unitExcelErrorDTO.getParentName());
			cell.setCellStyle(cellStyle);

			// 第二列
			Cell cell2 = row.createCell(1);
			cell2.setCellValue(unitExcelErrorDTO.getParentChainCode());
			cell2.setCellStyle(cellStyle);

			Cell cell3 = row.createCell(2);
			cell3.setCellValue(unitExcelErrorDTO.getName());
			cell3.setCellStyle(cellStyle);

			Cell cell4 = row.createCell(3);
			cell4.setCellValue(unitExcelErrorDTO.getCode());
			cell4.setCellStyle(cellStyle);

			Cell cell5 = row.createCell(4);
			cell5.setCellValue(unitExcelErrorDTO.getReason());
			cell5.setCellStyle(cellStyle);
		}
		ExcelUtils.buildExcelDocument(fileName, workbook, response);
	}

	public void spaceImportResult(Integer typeId, Workbook wb, List<ErrorSpace<JSONObject>> data){

		OrganizationType organizationType = organizationTypeService.getById(typeId);
		JSONObject jsonObject = JSONObject.parseObject(organizationType.getSource());
		List<String> fields = new ArrayList<>();
		Map<String, String> map = new HashMap<>();
		List<String> fieldList = (List<String>) jsonObject.get("order");
		if(CollectionUtil.isNotEmpty(fieldList)){
			fields.addAll(fieldList);
		}else {
			JSONArray jsonArray = jsonObject.getJSONArray("fields");
			if (jsonArray != null && jsonArray.size() > 0) {
				for (int i = 0; i < jsonArray.size(); i++) {
					if ("sortField".equals(jsonArray.getJSONObject(i).getString("vModel"))){
						continue;
					}
					fields.add(jsonArray.getJSONObject(i).getString("vModel"));
					map.put(jsonArray.getJSONObject(i).getString("vModel"), jsonArray.getJSONObject(i).getString("label"));
				}
			}
		}
		// cnname enname 映射
		JSONObject formDesc = (JSONObject) jsonObject.get("formDesc");

		// Map<中文名，英文名>
		Map<String, String> CNENMap = new HashMap<>();
		if(CollectionUtil.isNotEmpty(fieldList)) {
			for (String field : fields) {
				JSONObject jsonObject1 = (JSONObject) formDesc.get(field);
				CNENMap.put(field, (String) jsonObject1.get("label"));
			}
		}else{
			CNENMap = map;
		}

		// 导入模版
		writeSpaceTemplateExcel(fields, jsonObject, wb,map,organizationType.getName());
		// 在最后增加一个‘原因’列
		Sheet sheet = wb.getSheetAt(0);
		Integer cellIndex = fields.size() + 2;
		Cell reasonCell = sheet.getRow(1).createCell(cellIndex);
		reasonCell.setCellValue("原因");
		// 写入数据
		int rowNum = 2;
		for (ErrorSpace<JSONObject> datum : data) {
			Row row = sheet.createRow(rowNum);
			//Space obj = datum.getObj();
			//String data1 = obj.getData();
			JSONObject object = datum.getObj();
			// 上级空间名称和上级空间编码
			Cell cell = row.createCell(0);
			cell.setCellValue(object.getString("parentName"));
			Cell cell1 = row.createCell(1);
			cell1.setCellValue(object.getString("parentChainCode"));
			int cellNum = 2;
			for (String field : fields) {
				Cell cell2 = row.createCell(cellNum);
				cell2.setCellValue(object.getString(field));
				cellNum ++;
			}
			// 原因
			Cell cell3 = row.createCell(cellNum);
			cell3.setCellValue(datum.getReason());
			rowNum ++;
		}
	}

	public void areaImportResult(HttpServletResponse response, Short industryId, List<AreaExcelErrorDTO> data, String fileName){
		String errorFilePath = getErrorFilePath(OrganizationTypeEnum.AREA.id.intValue(), industryId);
		InputStream is = null;
		try {
			is = new FileInputStream(errorFilePath);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		Workbook workbook = null;
		if (fileName.endsWith(EXCEL2007)) {
			try {
				workbook = new XSSFWorkbook(is);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		if (fileName.endsWith(EXCEL2003)) {
			try {
				workbook = new HSSFWorkbook(is);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		// 设置格式
		Sheet sheet = workbook.getSheetAt(0);
		CellStyle cellStyle = workbook.createCellStyle();
		cellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
		cellStyle.setAlignment(HorizontalAlignment.CENTER);
		Font font = workbook.createFont();
		cellStyle.setFont(font);
		ExcelUtils.setByColName(data, AreaExcelErrorDTO.class, sheet, 2);
		ExcelUtils.buildExcelDocument(fileName, workbook, response);
	}

	public void publicAreaImportResult(HttpServletResponse response, Short industryId, List<PublicAreaExcelErrorDTO> data, String fileName){
		String errorFilePath = getErrorFilePath(OrganizationTypeEnum.PUBLIC_AREA.id.intValue(), industryId);
		InputStream is = null;
		try {
			is = new FileInputStream(errorFilePath);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		Workbook workbook = null;
		if (fileName.endsWith(EXCEL2007)) {
			try {
				workbook = new XSSFWorkbook(is);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		if (fileName.endsWith(EXCEL2003)) {
			try {
				workbook = new HSSFWorkbook(is);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		// 设置格式
		Sheet sheet = workbook.getSheetAt(0);
		CellStyle cellStyle = workbook.createCellStyle();
		cellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
		cellStyle.setAlignment(HorizontalAlignment.CENTER);
		Font font = workbook.createFont();
		cellStyle.setFont(font);
		ExcelUtils.setByColName(data, PublicAreaExcelErrorDTO.class, sheet, 2);
		ExcelUtils.buildExcelDocument(fileName, workbook, response);
	}

	public void roomImportResult(HttpServletResponse response, Short industryId, List<RoomExcelErrorDTO> data, String fileName){
		String errorFilePath = getErrorFilePath(OrganizationTypeEnum.ROOM.id.intValue(), industryId);
		InputStream inputStream = null;
		try {
			inputStream = new FileInputStream(errorFilePath);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		Workbook workbook = null;
		if (fileName.endsWith(EXCEL2007)) {
			try {
				workbook = new XSSFWorkbook(inputStream);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		if (fileName.endsWith(EXCEL2003)) {
			try {
				workbook = new HSSFWorkbook(inputStream);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		 Sheet sheet = workbook.getSheetAt(0);

		CellStyle cellStyle = workbook.createCellStyle();
		cellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
		cellStyle.setAlignment(HorizontalAlignment.CENTER);
		Font font = workbook.createFont();
		cellStyle.setFont(font);
		ExcelUtils.setByColName(data, RoomExcelErrorDTO.class, sheet, 2);
		ExcelUtils.buildExcelDocument(fileName, workbook, response);
	}

	public void buildingImportResult(HttpServletResponse response, Short industryId, List<BuildingExcelErrorDTO> data, String fileName){

		String filePath = getFilePath(OrganizationTypeEnum.BUILDING.id.intValue(), industryId);
		InputStream is = null;
		try {
			is = new FileInputStream(filePath);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		Workbook workbook = null;
		if (fileName.endsWith(EXCEL2007)) {
			try {
				workbook = new XSSFWorkbook(is);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		if (fileName.endsWith(EXCEL2003)) {
			try {
				workbook = new HSSFWorkbook(is);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		// 设置格式
		Sheet sheet = workbook.getSheetAt(0);
		CellStyle cellStyle = workbook.createCellStyle();
		cellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
		cellStyle.setAlignment(HorizontalAlignment.CENTER);
		Font font = workbook.createFont();
		cellStyle.setFont(font);

		if(3 == industryId){
			Row row = sheet.getRow(1);
			Cell cell = row.createCell(5);
			cell.setCellValue("原因");
			cell.setCellStyle(cellStyle);
		}else{
			Row row = sheet.getRow(1);
			Cell cell = row.createCell(4);
			cell.setCellValue("原因");
			cell.setCellStyle(cellStyle);
		}

		// 从第三行开始往后写入
		for (int i = 0; i < data.size(); i++) {
			Row row = sheet.createRow(i+2);
			BuildingExcelErrorDTO buildingExcelErrorDTO = data.get(i);
			// 第一列
			Cell cell = row.createCell(0);
			cell.setCellValue(buildingExcelErrorDTO.getParentName());
			cell.setCellStyle(cellStyle);

			// 第二列
			Cell cell2 = row.createCell(1);
			cell2.setCellValue(buildingExcelErrorDTO.getParentChainCode());
			cell2.setCellStyle(cellStyle);

			Cell cell3 = row.createCell(2);
			cell3.setCellValue(buildingExcelErrorDTO.getName());
			cell3.setCellStyle(cellStyle);

			if(industryId == 3){
				Cell cell4 = row.createCell(3);
				cell4.setCellValue(buildingExcelErrorDTO.getType());
				cell4.setCellStyle(cellStyle);

				Cell cell5 = row.createCell(4);
				cell5.setCellValue(buildingExcelErrorDTO.getCode());
				cell5.setCellStyle(cellStyle);

				Cell cell6 = row.createCell(5);
				cell6.setCellValue(buildingExcelErrorDTO.getReason());
				cell6.setCellStyle(cellStyle);
			}else{

				Cell cell5 = row.createCell(3);
				cell5.setCellValue(buildingExcelErrorDTO.getCode());
				cell5.setCellStyle(cellStyle);

				Cell cell4 = row.createCell(4);
				cell4.setCellValue(buildingExcelErrorDTO.getReason());
				cell4.setCellStyle(cellStyle);
			}
		}
		ExcelUtils.buildExcelDocument(fileName, workbook, response);
	}


	public void floorImportResult(HttpServletResponse response, Short industryId, List<FloorExcelErrorDTO> data, String fileName){

		String filePath = getFilePath(OrganizationTypeEnum.FLOOR.id.intValue(), industryId);
		InputStream is = null;
		try {
			is = new FileInputStream(filePath);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		Workbook workbook = null;
		if (fileName.endsWith(EXCEL2007)) {
			try {
				workbook = new XSSFWorkbook(is);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		if (fileName.endsWith(EXCEL2003)) {
			try {
				workbook = new HSSFWorkbook(is);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		// 设置格式
		Sheet sheet = workbook.getSheetAt(0);
		CellStyle cellStyle = workbook.createCellStyle();
		cellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
		cellStyle.setAlignment(HorizontalAlignment.CENTER);
		Font font = workbook.createFont();
		cellStyle.setFont(font);

		if(3 == industryId){
			Row row = sheet.getRow(1);
			Cell cell = row.createCell(5);
			cell.setCellValue("原因");
			cell.setCellStyle(cellStyle);
		}else{
			Row row = sheet.getRow(1);
			Cell cell = row.createCell(4);
			cell.setCellValue("原因");
			cell.setCellStyle(cellStyle);
		}

		// 从第三行开始往后写入
		for (int i = 0; i < data.size(); i++) {
			Row row = sheet.createRow(i+2);
			FloorExcelErrorDTO floorExcelErrorDTO = data.get(i);
			// 第一列
			Cell cell = row.createCell(0);
			cell.setCellValue(floorExcelErrorDTO.getParentName());
			cell.setCellStyle(cellStyle);

			// 第二列
			Cell cell2 = row.createCell(1);
			cell2.setCellValue(floorExcelErrorDTO.getParentChainCode());
			cell2.setCellStyle(cellStyle);

			Cell cell3 = row.createCell(2);
			cell3.setCellValue(floorExcelErrorDTO.getName());
			cell3.setCellStyle(cellStyle);

			if(industryId == 3){
				Cell cell4 = row.createCell(3);
				cell4.setCellValue(floorExcelErrorDTO.getType());
				cell4.setCellStyle(cellStyle);

				Cell cell5 = row.createCell(4);
				cell5.setCellValue(floorExcelErrorDTO.getCode());
				cell5.setCellStyle(cellStyle);

				Cell cell6 = row.createCell(5);
				cell6.setCellValue(floorExcelErrorDTO.getReason());
				cell6.setCellStyle(cellStyle);
			}else{
				Cell cell4 = row.createCell(3);
				cell4.setCellValue(floorExcelErrorDTO.getCode());
				cell4.setCellStyle(cellStyle);

				Cell cell5 = row.createCell(4);
				cell5.setCellValue(floorExcelErrorDTO.getReason());
				cell5.setCellStyle(cellStyle);
			}
		}
		ExcelUtils.buildExcelDocument(fileName, workbook, response);
	}

	/**
	 * 空间模版导出
	 * @param response
	 * @param typeId
	 * @param industryId
	 */
	@RequestMapping(value = "/space/template-export")
	public void downloadTemplate(HttpServletResponse response, @RequestParam Integer typeId, @RequestParam Integer projectId, @RequestHeader Short industryId){

		OrganizationType organizationType = organizationTypeService.getById(typeId);
		if(null == organizationType){
			log.info("类型不存在");
			return ;
		}

		List<ParentOrgDTO> parentInfo = getParentInfo(projectId, typeId);

		parentInfo = parentInfo.stream().filter(i -> !StringUtils.isEmpty(i.getParentName())).collect(Collectors.toList());
		// 自定义空间导出
		//if(organizationType.getViewType() == ViewType.SPACE_DEFINED){
		String source = organizationType.getSource();
		if(StringUtils.isEmpty(source)){
			log.info("空间配置错误");
			return;
		}
		JSONObject jsonObject = JSONObject.parseObject(source);
		List<String> fields = new ArrayList<>();
		//List<String> fieldList = (List<String>) jsonObject.get("order");
		//出来新数据
		Map<String, String> map = new HashMap<>();
			/*if(CollectionUtil.isNotEmpty(fieldList)){
				fields.addAll(fieldList);
			}else {*/
		JSONArray jsonArray = jsonObject.getJSONArray("fields");
		if (jsonArray != null && jsonArray.size() > 0) {
			for (int i = 0; i < jsonArray.size(); i++) {
				//地理围栏不导入
				if("fc-map-fence".equals(jsonArray.getJSONObject(i).getString("tag"))){
					continue;
				}
				if("sortField".equals(jsonArray.getJSONObject(i).getString("vModel"))){
					continue;
				}					fields.add(jsonArray.getJSONObject(i).getString("vModel"));
				map.put(jsonArray.getJSONObject(i).getString("vModel"), jsonArray.getJSONObject(i).getString("label"));
			}
		}
		//}
		Workbook wb = new XSSFWorkbook();
		writeSpaceTemplateExcel(fields, jsonObject, wb,map,organizationType.getName());
		writeParentInfo(parentInfo, wb);
		buildExcelDocument("TEMPLATE.xlsx", wb, response);
		/*}else if(organizationType.getViewType() == ViewType.SPACE){
			String filePath = getFilePath(typeId, industryId);
			File file = new File(filePath);

			if(file.exists()){
				response.setHeader("content-type", "application/octet-stream");
				response.setContentType("application/octet-stream");
				response.setHeader("Content-Disposition", "attachment;filename=" + getFileName(typeId) + ".xlsx");
				response.setHeader("Access-Control-Expose-Headers","Content-Disposition");
				FileInputStream fis = null;
				BufferedInputStream bis = null;

				try {
					fis = new FileInputStream(file);

					Workbook workbook = null;
					try {
						workbook = new XSSFWorkbook(fis);
					} catch (IOException e) {
						e.printStackTrace();
					}
					writeParentInfo(parentInfo, workbook);
					workbook.write(response.getOutputStream());
				} catch (Exception e) {
					log.error(e.getMessage());
				} finally {
					if (bis != null) {
						try {
							bis.close();
						} catch (IOException e) {
							e.printStackTrace();
						}
					}
					if (fis != null) {
						try {
							fis.close();
						} catch (IOException e) {
							e.printStackTrace();
						}
					}
				}
			}else{
				log.error("文件 {} 不存在", filePath);
			}
		}*/
	}

	public void writeParentInfo(List<ParentOrgDTO> parentInfo, Workbook wb){
		if(CollectionUtils.isNotEmpty(parentInfo)){
			Sheet sheetAt = wb.getSheetAt(0);
			int i = 2;
			for (ParentOrgDTO parentOrgDTO : parentInfo) {
				Row row = sheetAt.createRow(i);
				Cell cell = row.createCell(0);
				cell.setCellValue(parentOrgDTO.getParentName());
				Cell cell1 = row.createCell(1);
				cell1.setCellValue(parentOrgDTO.getParentCode());
				i++;
			}
		}
	}

	public List<ParentOrgDTO> getParentInfo(Integer projectId, Integer type){
		List<ParentOrgDTO> result = new ArrayList<>();
		OrganizationConfigQuery organizationConfigQuery = new OrganizationConfigQuery();
		organizationConfigQuery.withProjectId(projectId);
		// 获取该空间类型所有的上级空间类型
		List<OrganizationConfig> parent = organizationConfigService.parent(organizationConfigQuery, type);

		if(parent.isEmpty()){
			log.warn("从配置中没有获取到满足条件的上级空间类型");
			return Collections.emptyList();
		}
		// 获得 type 上级的所有类型
		List<Integer> parentType = parent.stream().map(i -> i.getType()).distinct().collect(Collectors.toList());
		QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
		organizationQueryWrapper.select("id", "parent_id", "type");
		organizationQueryWrapper.in("type", parentType);
		organizationQueryWrapper.eq("project_id", projectId);
		List<Organization> parentOrganizations = organizationService.list(organizationQueryWrapper);
		if(parentOrganizations.isEmpty()){
			log.warn("填写导出空间模版excel上级空间信息，没有合适的空间数据");
			return Collections.emptyList();
		}
		List<Integer> parentOrganizationIds = parentOrganizations.stream().map(i -> i.getId()).collect(Collectors.toList());
		OrganizationQuery organizationQuery = new OrganizationQuery();
		organizationQuery.withIds(parentOrganizationIds);
		List<Integer> integers = organizationTypeService.spaceIds();
		integers.add(OrganizationTypeEnum.PROJECT.id.intValue());
		organizationQuery.withTypes(integers);
		Map<Integer, String> nameMap = organizationService.batchFullName(organizationQuery);
		Map<Integer, String> codeMap = organizationService.batchFullCode(organizationQuery);

		for (Integer parentOrganizationId : parentOrganizationIds) {
			ParentOrgDTO parentOrgDTO = new ParentOrgDTO();
			parentOrgDTO.setOrganizationId(parentOrganizationId);
			parentOrgDTO.setParentCode(codeMap.get(parentOrganizationId));
			parentOrgDTO.setParentName(nameMap.get(parentOrganizationId));
			result.add(parentOrgDTO);
		}
		return result;
	}

	private static String getErrorFilePath(Integer typeId, Short industryId){
		String fileName = getFileName(typeId);
		if(StringUtils.isEmpty(fileName)){
			log.error("类型不存在");
			return null;
		}
		String basePath = null;
		try {
			basePath = ResourceUtils.getURL("classpath:").getPath();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		String filePath;
		if(OrganizationTypeEnum.AREA.id.intValue() == typeId){
			filePath = basePath + "template/" + "error/" + fileName + ".xlsx";
		} else {
			filePath = basePath + "template/" + industryId + "/error/" + fileName + ".xlsx";
		}
		return filePath;
	}

	private static String getFilePath(Integer typeId, Short industryId){
		String fileName = getFileName(typeId);
		if(StringUtils.isEmpty(fileName)){
			log.error("类型不存在");
			return null;
		}
		String basePath = null;
		try {
			basePath = ResourceUtils.getURL("classpath:").getPath();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		String filePath;
		if(OrganizationTypeEnum.AREA.id.intValue() == typeId || OrganizationTypeEnum.UNIT.id.intValue() == typeId){
			filePath = basePath + "template/" + fileName + ".xlsx";
		} else {
			filePath = basePath + "template/" + 2 + "/" + fileName + ".xlsx";
		}
		return filePath;
	}

	private static String getFileName(Integer typeId){
		Map<Integer, String> map = new HashMap<>();
		map.put(3, "BUILDING_MODEL_TEMPLATE");// 楼栋
		map.put(5, "FLOOR_MODEL_TEMPLATE");// 楼层
		map.put(6, "ROOM_MODEL_TEMPLATE");// 房间
		map.put(7, "AREA_MODEL_TEMPLATE");// 区域
		map.put(11, "PUBLIC_AREA_MODEL_TEMPLATE");// 公区
		map.put(13, "UNIT_MODEL_TEMPLATE");//单元
		map.put(14, "BLOCK_MODEL_TEMPLATE");//地块
		map.put(15, "BALCONY_MODEL_TEMPLATE");//楼座
		return map.get(typeId);
	}


	private static void writeSpaceTemplateExcel(List<String> fields,JSONObject jsonObject, Workbook wb,Map<String,String> map,String typeName){
		Sheet sheet = wb.createSheet("Sheet1");
		//JSONObject formDesc = (JSONObject) spaceTypeConfig.get("formDesc");
		for(int i = 0; i < fields.size() + 2; i ++){
			sheet.setColumnWidth(i, 6000);
		}
		{
			//表头
			Row row = sheet.createRow(0);
			row.setHeight((short) 2500);
			Cell cell = row.createCell(0);

			CellStyle cellStyle = wb.createCellStyle();
			// 边框
			cellStyle.setBorderBottom(BorderStyle.THIN);
			cellStyle.setBorderLeft(BorderStyle.THIN);
			cellStyle.setBorderRight(BorderStyle.THIN);
			cellStyle.setBorderTop(BorderStyle.THIN);

			cellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
			cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
			cellStyle.setAlignment(HorizontalAlignment.CENTER);
			cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
			// 自动换行
			cellStyle.setWrapText(true);

			Font font = wb.createFont();
			cellStyle.setFont(font);
			cell.setCellStyle(cellStyle);
			cell.setCellValue("上级的空间名称");


			Cell cell1 = row.createCell(1);
			cell1.setCellStyle(cellStyle);
			cell1.setCellValue("上级空间的空间编码，若上一级为项目则为项目编码");

			/*Cell cell2 = row.createCell(2);
			cell2.setCellStyle(cellStyle);
			cell2.setCellValue("自定义填写，不超过50个字符（必填）");*/

			Map<String,String> msgMap = new HashMap<>();
			JSONArray jsonArray = jsonObject.getJSONArray("fields");
			if (jsonArray != null && jsonArray.size() > 0) {
				for (int i = 0; i < jsonArray.size(); i++) {
					//地理围栏不导入
					if("fc-map-fence".equals(jsonArray.getJSONObject(i).getString("tag"))){
						continue;
					}
					if("sortField".equals(jsonArray.getJSONObject(i).getString("vModel"))){
						continue;
					}
					JSONObject vo = jsonArray.getJSONObject(i);
					String msg="";
					String label = vo.getString("label");
					if(StringUtils.isNotEmpty(label) && label.contains("面积")){
						msg = msg + "系统默认单位为“平方米”，精确到2位小数;";
					}
					/*if(StringUtils.isNotEmpty(label) && label.contains("名称")){
						msg = msg + "自定义填写，不超过50个字符;";
					}*/
					if(StringUtils.isNotEmpty(label) && label.contains("编码")){
						msg = msg + "编码若不填写则由系统自动生成。编码规则为：6-50个字符支持数字/字母/特殊字符(`~!@#$%^&*()-_=+\\|[{}];:'\",<.>/?);";
					}
					String tag = vo.getString("tag");
					if("el-select".equals(tag)){
						//获得k-v
						JSONArray options = vo.getJSONArray("options");
						if (options != null && options.size() > 0) {
							Boolean multiple = vo.getBoolean("multiple");
							if(null != multiple && multiple) {
								msg = msg + "请填写对应选项编号，可多选用'、'隔开;";
							}else{
								msg = msg + "请填写对应选项编号，限1个;";
							}
							for (int j = 0; j < options.size(); j++) {
								JSONObject jsonObject1 = options.getJSONObject(j);
								msg = msg +jsonObject1.getString("value") +":"+jsonObject1.getString("label")+";";
							}
						}
					} else if("el-input".equals(tag)){
						msg = msg + "自定义填写";
						Integer maxlength = vo.getInteger("maxlength");
						if(maxlength != null){
							msg = msg + "，不超过"+maxlength+"个字符;";
						}
					}else if("fc-input-number".equals(tag)){
						String unit = vo.getString("unit");
						if(unit != null){
							msg = msg + "系统默认单位为"+unit;
						}else{
							msg = msg + "未设置系统默认单位";
						}
						Integer precision = vo.getInteger("precision");
						if(precision != null && precision > 0){
							msg = msg +"，精确到"+precision+"位小数;";
						}else{
							msg = msg +"，未设置精确度;";
						}
					}else if("fc-area".equals(tag)){
						msg = msg +"请严格按照“XX省-XX市-XX区/县”填写，直辖市/港澳地区按照“XX-XX市-XX区/县”填写，如「北京-北京市-朝阳区」、「香港特别行政区-香港岛-中西区」";
					}
					Boolean required = vo.getBoolean("required");
					if(required != null && required){
						msg = msg + "(必填)";
					}
					msgMap.put(jsonArray.getJSONObject(i).getString("vModel"),msg);
				}
			}
			//添加说明
			int j = 2;
			for (String field : fields) {
				Cell rc2 = row.createCell(j);
				rc2.setCellStyle(cellStyle);
				//处理提示信息
				rc2.setCellValue(msgMap.get(field));
				j ++;
			}

			// 第二行
			Row row2 = sheet.createRow(1);
			CellStyle cellStyle2 = wb.createCellStyle();

			Cell rc0 = row2.createCell(0);
			rc0.setCellStyle(cellStyle2);
			rc0.setCellValue("上级空间名称");

			Cell rc1 = row2.createCell(1);
			rc1.setCellStyle(cellStyle2);
			rc1.setCellValue("上级空间编码");

			cellStyle.setWrapText(true);
			int i = 2;
			for (String field : fields) {
				Cell rc2 = row2.createCell(i);
				rc2.setCellStyle(cellStyle2);
				/*if(formDesc != null) {
					JSONObject object = (JSONObject) formDesc.get(field);
					String label = (String) object.get("label");
					rc2.setCellValue(label);
				}else {*/
				String val = map.get(field);
				rc2.setCellValue(getName(typeName,val));
				//}
				i ++;
			}
		}

		//冻结窗格
		wb.getSheet("Sheet1").createFreezePane(0, 2, 0, 2);
	}

	private static String getName(String typeName,String name){
		if(!("名称".equals(name) || "编码".equals(name)) ){
			return name;
		}
		return typeName+name;
	}

	private static void buildExcelDocument(String fileName, Workbook wb, HttpServletResponse response) {
		try {
			response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
			response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "utf-8"));
			response.flushBuffer();
			wb.write(response.getOutputStream());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Data
	class ParentOrgDTO{

		private Integer organizationId;

		private String parentName;

		private String parentCode;
	}

	private void dealJson (Space param,Integer typeId){
		QueryWrapper<OrganizationType> organizationTypeQueryWrapper = new QueryWrapper<>();
		organizationTypeQueryWrapper.eq("id", typeId);
		OrganizationType organizationType = organizationTypeService.getOne(organizationTypeQueryWrapper);
		String source = organizationType.getSource();
		if(org.apache.commons.lang3.StringUtils.isEmpty(source)){
			return;
		}
		Map<String,Object> map = new HashMap<>();
		JSONObject sourceJson = JSON.parseObject(source);
		JSONArray fields = sourceJson.getJSONArray("fields");
		if(CollectionUtil.isNotEmpty(fields)) {
			for (int i = 0; i < fields.size(); i++) {
				JSONObject fieldJsonObject = fields.getJSONObject(i);
				fieldJsonObject.remove("__config__");
				String vModel = fieldJsonObject.getString("vModel");
				//兼容以前数据
				if ("name".equals(vModel)) {
					fields.getJSONObject(i).put("defaultValue",param.getName() != null ? param.getName() : "");
					map.put("name",param.getName() != null ? param.getName() : "");
				} else if ("code".equals(vModel)) {
					fields.getJSONObject(i).put("defaultValue",param.getCode() != null ? param.getCode() : "");
					map.put("code",param.getCode() != null ? param.getCode() : "");
				}else if ("sortField".equals(vModel)){
					fields.getJSONObject(i).put("defaultValue",param.getSortField() != null ? param.getSortField() : "");
					map.put("sortField",param.getSortField() != null ? param.getSortField() : "");
				} else {
					if(param.getData() != null) {
						JSONObject jsonObject = JSON.parseObject(param.getData());
						if(jsonObject.get(vModel) != null) {
							fields.getJSONObject(i).put("defaultValue", jsonObject.get(vModel));
							map.put(vModel,jsonObject.get(vModel));
						}else{
							map.put(vModel,"");
						}
					}else{
						map.put(vModel,"");
					}
				}
			}
		}
		param.setExpand(JSON.toJSONString(sourceJson));
		param.setFullData(JSON.toJSONString(map));
	}
	/**
	 * 空间结构管理
	 * @return
	 */
	@RequestMapping(value = "/space/management/pageTree")
	public ResultJson pageTree(@RequestBody OrganizationConfigPageQuery organizationConfigPageQuery){
		Page page = organizationConfigFeignService.pageTree(organizationConfigPageQuery, organizationConfigPageQuery.getPage());
		return ResultJson.success(page);
	}
}
